﻿using System;
using System.Collections.Generic;
using System.Text;

namespace GraffitiExtras.Plugins.CommunityCredit
{
    /// <summary>
    /// Provides several methods that you can use with Community Credit webservices.
    /// </summary>
    internal class CommunityCreditService
    {
        #region Properties and Fields

        private string _affiliateCode = string.Empty;
        private string _affiliateKey = string.Empty;

        #endregion

        #region Constructors

        /// <summary>
        /// Public constructor that uses the default affiliate code and affiliate key.
        /// </summary>
        public CommunityCreditService()
        {
            this._affiliateCode = "KNGR0611#~";
            this._affiliateKey = "25BB1EDA5C7547";
        }

        #endregion

        #region Public methods

        /// <summary>
        /// Adds community credit for a specified task for current date.
        /// </summary>
        /// <param name="earner">The earner.</param>
        /// <param name="task">The task.</param>
        public void AddCommunityCredit(Earner earner, Task task)
        {
            ServiceClient client = new ServiceClient(this._affiliateCode, this._affiliateKey);

            string result = client.AddCommunityCredit(earner.Email, earner.FirstName, earner.LastName,
                task.Description, task.URL, task.Category.Code);

            if (result != "Success")
                throw new CommunityCreditException(result);
        }

        /// <summary>
        /// Adds community credit for a specified task for specified date.
        /// </summary>
        /// <param name="earner">The earner.</param>
        /// <param name="task">The task.</param>
        /// <param name="dateEarned">The date when the task is earned.</param>
        public void AddCommunityCredit(Earner earner, Task task, DateTime dateEarned)
        {
            ServiceClient client = new ServiceClient(this._affiliateCode, this._affiliateKey);

            string result = client.AddCommunityCreditByDate(earner.Email, earner.FirstName, earner.LastName,
                task.Description, task.URL, task.Category.Code, dateEarned);

            if (result != "Success")
                throw new CommunityCreditException(result);
        }

        /// <summary>
        /// Adds credit for a newgroup.
        /// </summary>
        /// <param name="earner">The earner.</param>
        /// <param name="task">The task.</param>
        /// <param name="dateEarned">The date when the task is earned.</param>
        public void AddNewsgroupCredit(Earner earner, Task task, DateTime dateEarned)
        {
            ServiceClient client = new ServiceClient(this._affiliateCode, this._affiliateKey);

            string result = client.AddNewsgroupCredit(earner.Email, earner.FirstName, earner.LastName,
                task.Description, task.URL, task.Category.Code, dateEarned);

            if (result != "Success")
                throw new CommunityCreditException(result);
        }

        /// <summary>
        /// Adds credit for a newsgroup item.
        /// </summary>
        /// <param name="newsgroupItem">The newsgroup item.</param>
        public void AddNewsgroupItem(NewsgroupItem newsgroupItem)
        {
            ServiceClient client = new ServiceClient(this._affiliateCode, this._affiliateKey);

            string result = client.AddNewsgroupItem(newsgroupItem.MessageID, newsgroupItem.ReferenceID,
                newsgroupItem.NewsgroupID, newsgroupItem.User, newsgroupItem.Subject,
                newsgroupItem.Message, newsgroupItem.Date.ToString());

            if (result != "Success")
                throw new CommunityCreditException(result);
        }

        /// <summary>
        /// Submits a specified blog to the service.
        /// </summary>
        /// <param name="blog">The blog.</param>
        public void AutoSubmitBlog(Blog blog)
        {
            ServiceClient client = new ServiceClient(this._affiliateCode, this._affiliateKey);

            string result = client.AutoSubmitBlog(blog.FeedUrl, blog.Url, blog.Title, blog.Date);

            if (result != "Success")
                throw new CommunityCreditException(result);
        }

        /// <summary>
        /// Gets the list of current month's prizes.
        /// </summary>
        /// <returns>An instance of PrizeCollection for prizes.</returns>
        public PrizeCollection GetCurrentContestPrizes()
        {
            ServiceClient client = new ServiceClient(this._affiliateCode, this._affiliateKey);

            return CcUtil.GetPrizesFromDataSet(client.CurrentContestPrizes());
        }

        /// <summary>
        /// Generate future credit for a task.
        /// </summary>
        /// <param name="earner">The earner.</param>
        /// <param name="task">The task.</param>
        public void GenerateFutureCredit(Earner earner, Task task)
        {
            ServiceClient client = new ServiceClient(this._affiliateCode, this._affiliateKey);

            string result = client.GenerateFutureCredit(earner.Email, earner.FirstName, earner.LastName,
                task.Description, task.URL, task.Category.Code);

            if (result != "Success")
                throw new CommunityCreditException(result);
        }

        /// <summary>
        /// Gets a list of demographics for all tasks.
        /// </summary>
        /// <returns>An instance of DemographicCollection for demographics.</returns>
        public DemographicCollection GetDemographics()
        {
            ServiceClient client = new ServiceClient(this._affiliateCode, this._affiliateKey);

            return CcUtil.GetDemographicsFromDataSet(client.GetDemographics());
        }

        /// <summary>
        /// Gets a list of earners for a specified date range.
        /// </summary>
        /// <param name="email">The email address of the earner.</param>
        /// <param name="startDate">The start date for the date range.</param>
        /// <param name="endDate">The end date for the date range.</param>
        /// <returns>An instance of EarnersCreditCollection for earners.</returns>
        public EarnersCreditCollection GetEarnersByDateRangeAndEmail(string email,
            DateTime startDate, DateTime endDate)
        {
            ServiceClient client = new ServiceClient(this._affiliateCode, this._affiliateKey);

            return CcUtil.GetEarnersCreditFromDataSet(client.GetEarnersByDateRangeAndEmail
                (email, startDate.ToString(), endDate.ToString()));
        }

        /// <summary>
        /// Gets a list of top earners overall.
        /// </summary>
        /// <returns>An instance of TopEarnerCollection for top earners.</returns>
        public TopEarnerCollection GetTopEarners()
        {
            ServiceClient client = new ServiceClient(this._affiliateCode, this._affiliateKey);

            return CcUtil.GetTopEarnersFromDataSet(client.GetTopEarners());
        }

        /// <summary>
        /// Gets a list of top earners for a specified date range.
        /// </summary>
        /// <param name="startDate">The start date for the date range.</param>
        /// <param name="endDate">The end date for the date range.</param>
        /// <returns>An instance of TopEarnerCollection for top earners.</returns>
        public TopEarnerCollection GetTopEarners(DateTime startDate, DateTime endDate)
        {
            ServiceClient client = new ServiceClient(this._affiliateCode, this._affiliateKey);

            return CcUtil.GetTopEarnersFromDataSet(client.GetTopEarnersByDateRange(startDate.ToString(),
                endDate.ToString()));
        }

        /// <summary>
        /// Gets a list of point categories for various community activities.
        /// </summary>
        /// <returns>An instance of PointCategoryCollection for point categories.</returns>
        public PointCategoryCollection GetPointCategories()
        {
            ServiceClient client = new ServiceClient(this._affiliateCode, this._affiliateKey);

            return CcUtil.GetCategoriesFromDataSet(client.PointCategoriesAll());
        }

        /// <summary>
        /// Sends a confirmation email to the registered user on Community Credit site.
        /// </summary>
        /// <param name="email">An email address that must be registered on Community Credit site.</param>
        /// <param name="firstName">The user's first name.</param>
        public void SendConfirmationEmail(string email, string firstName)
        {
            ServiceClient client = new ServiceClient(this._affiliateCode, this._affiliateKey);

            client.SendConfirmationEmail(email, firstName);
        }

        /// <summary>
        /// Sends an email to introduce Community Credit site to new users.
        /// </summary>
        /// <param name="senderName">The sender's name.</param>
        /// <param name="receiverEmail">The receiver's email adddress.</param>
        /// <param name="receiverFirstName">The receiver's first name.</param>
        /// <param name="receiverLastName">The receiver's last name.</param>
        public void Spread(string senderName, string receiverEmail, string receiverFirstName,
            string receiverLastName)
        {
            ServiceClient client = new ServiceClient(this._affiliateCode, this._affiliateKey);

            string result = client.SpreadTheWord(senderName, receiverEmail,
                receiverFirstName, receiverLastName);

            if (result != "Success")
                throw new CommunityCreditException(result);
        }

        #endregion
    }
}
